home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-PPC / MMU_CONT.{17 < prev    next >
Text File  |  1999-09-17  |  3KB  |  92 lines

  1. #include <linux/config.h>
  2.  
  3. #ifndef __PPC_MMU_CONTEXT_H
  4. #define __PPC_MMU_CONTEXT_H
  5.  
  6. /* the way contexts are handled on the ppc they are vsid's and
  7.    don't need any special treatment right now.
  8.    perhaps I can defer flushing the tlb by keeping a list of
  9.    zombie vsid/context's and handling that through destroy_context
  10.    later -- Cort
  11.  
  12.    The MPC8xx has only 16 contexts.  We rotate through them on each
  13.    task switch.  A better way would be to keep track of tasks that
  14.    own contexts, and implement an LRU usage.  That way very active
  15.    tasks don't always have to pay the TLB reload overhead.  The
  16.    kernel pages are mapped shared, so the kernel can run on behalf
  17.    of any task that makes a kernel entry.  Shared does not mean they
  18.    are not protected, just that the ASID comparison is not performed.
  19.         -- Dan
  20.  */
  21.  
  22. #ifdef CONFIG_8xx
  23. #define NO_CONTEXT      16
  24. #define LAST_CONTEXT    15
  25. #define MUNGE_CONTEXT(n)        (n)
  26.  
  27. #else
  28.  
  29. /* PPC 6xx, 7xx CPUs */
  30. #define NO_CONTEXT      0
  31. #define LAST_CONTEXT    0xfffff
  32.  
  33. /*
  34.  * Allocating context numbers this way tends to spread out
  35.  * the entries in the hash table better than a simple linear
  36.  * allocation.
  37.  */
  38. #define MUNGE_CONTEXT(n)        (((n) * 897) & LAST_CONTEXT)
  39. #endif
  40.  
  41. extern atomic_t next_mmu_context;
  42. extern void mmu_context_overflow(void);
  43.  
  44. #ifndef CONFIG_8xx
  45. extern void set_context(int context);
  46. #else
  47. #define set_context(context)    do { } while (0)
  48. #endif
  49.  
  50. /*
  51.  * Get a new mmu context for task tsk if necessary.
  52.  */
  53. #define get_mmu_context(tsk)                    \
  54. do {                                 \
  55.     struct mm_struct *mm = (tsk)->mm;            \
  56.     if (mm->context == NO_CONTEXT) {            \
  57.         if (atomic_read(&next_mmu_context) == LAST_CONTEXT)        \
  58.             mmu_context_overflow();            \
  59.         mm->context = MUNGE_CONTEXT(atomic_inc_return(&next_mmu_context));\
  60.     }                            \
  61. } while (0)
  62.  
  63. /*
  64.  * Set up the context for a new address space.
  65.  */
  66. #define init_new_context(mm)    ((mm)->context = NO_CONTEXT)
  67.  
  68. /*
  69.  * We're finished using the context for an address space.
  70.  */
  71. #define destroy_context(mm)     do { } while (0)
  72.  
  73. /*
  74.  * After we have set current->mm to a new value, this activates
  75.  * the context for the new mm so we see the new mappings.
  76.  */
  77. extern inline void activate_context(struct task_struct *tsk)
  78. {
  79.     get_mmu_context(tsk);
  80.     set_context(tsk->mm->context);
  81. }
  82.  
  83. /*
  84.  * compute the vsid from the context and segment
  85.  * segments > 7 are kernel segments and their
  86.  * vsid is the segment -- Cort
  87.  */
  88. #define    VSID_FROM_CONTEXT(segment,context) \
  89.    ((segment < 8) ? ((segment) | (context)<<4) : (segment))
  90.  
  91. #endif
  92.